﻿using System;
using System.Configuration;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
using NLog;
using TfsGiggle.Core;
using System.Threading.Tasks;

namespace TfsGiggle.EngineService
{
    /// <summary>
    /// The service
    /// </summary>
    public partial class TfsGiggleService : ServiceBase
    {
        private static LoggerWithEventId _logger = (LoggerWithEventId)LogManager.GetCurrentClassLogger(typeof(LoggerWithEventId));
        private CancellationTokenSource _tokenSource = new CancellationTokenSource();
        private WCFUtil _hostService = new WCFUtil();
        private int[] _subscriptionIds;

        /// <summary>
        /// The TfsGiggle service
        /// </summary>
        public TfsGiggleService()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Starts all TfsGiggle dependencies
        /// </summary>
        /// <param name="args"></param>
        protected override void OnStart(string[] args)
        {
            _logger.Trace("enter");
            if (args != null && args.Length > 0 && args[0].ToLowerInvariant().Equals("debug"))
            {
                Debugger.Launch();
            }
            Thread serviceThread = new Thread(new ThreadStart(Start));
            serviceThread.IsBackground = true;
            serviceThread.Start();
        }

        private void Start()
        {
            _logger.Trace("enter");
            try
            {
                var dataDirectory = ConfigurationManager.AppSettings["DataDirectory"];
                var tfsUri = new Uri(ConfigurationManager.AppSettings["TfsUrl"]);
                var tfsConfigurationServer = TfsConfigurationServerFactoryImpl.GetConfigurationServer(tfsUri);
                var port = Int32.Parse(ConfigurationManager.AppSettings["Port"]);
                JobManager.Instance.Open(dataDirectory, tfsConfigurationServer, _tokenSource.Token);
                var subscriptionUris = _hostService.HostThisService(port);
                _subscriptionIds = TfsUtil.SubscribeToCheckinEvents(tfsUri, subscriptionUris[0]);
                _logger.Info("TfsGiggle started");
            }
            catch (Exception ex)
            {
                _logger.FatalExceptionWithEventId(EventId.BackgroundStart, "ups", ex);
                base.Stop();
                Environment.FailFast("Exception caught in Start()", ex);
            }
        }

        /// <summary>
        /// Stops all TfsGiggle dependencies
        /// </summary>
        protected override void OnStop()
        {
            _logger.Trace("enter");
            try
            {
                var tfsUri = new Uri(ConfigurationManager.AppSettings["TfsUrl"]);
                TfsUtil.UnSubscribeToCheckinEvent(tfsUri, _subscriptionIds);
                _hostService.Dispose();
                _tokenSource.Cancel();
                _tokenSource.Dispose();
                JobManager.Instance.Dispose();
                _logger.Info("Service stopped");
            }
            catch (Exception exception)
            {
                _logger.ErrorExceptionWithEventId(EventId.OnStopException, "Bad things happened in OnStop", exception);
            }
        }
    }
}